from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, QTimer
import os
import time
from libs.ioctrl import IoCtrl
from libs import globalvar
from libs.player import SoundPlayer
import RPi.GPIO as GPIO
import threading

from libs.counter import ImageCounter
from libs.qrcode import Qrcode
from libs.config import Din2, LedPin, LEDLightTimeLen

#https://stackoverflow.com/questions/36175717/importerror-no-module-named-pyqt5-qtquick
# 树莓派 PyQt5 的 qquick 缺失解决
# sudo apt-get install python3-pyqt5.qtquick


# 定义一个类，将我们需要用到的方法、变量等都放到里面，便于调用
class CounterHandler(QObject):

    counterNewValue = pyqtSignal(int, arguments=['counterValue'])

    def __init__(self):
        super().__init__()
        self.timer = QTimer(interval=1000, timeout=self._ledTimer)
        self.timer.start()
        
        # 各种初始化
        IoCtrl.gpioinit()
        globalvar._init()
        SoundPlayer.init()

        self.counterProcessing = False

        self.restLedLight = 0
    
        self.edgeThread = threading.Thread(target=self.threadEdgeDetect, args=(self,))
        self.edgeThread.setDaemon(True)
        self.edgeThread.start()

    @pyqtSlot()
    def counterStart(self):
        #self.bindPinHandler()
        self.counterProcessing = True

    @pyqtSlot()
    def counterStop(self):
        self.counterProcessing = False

    '''
        LED 补光灯延迟
    '''
    def _ledTimer(self):
        if self.restLedLight > 0:
            GPIO.output(LedPin, 1)
        else:
            GPIO.output(LedPin, 0)
        self.restLedLight = self.restLedLight - 1
        if(self.restLedLight < 0):
            self.restLedLight = 0

    def openLightDelayClose(self):
        self.restLedLight = 3
        GPIO.output(LedPin, 1)


    #线程后台计数，延迟比较大
    def threadEdgeDetect(self, obj):
        while True:

            if obj.counterProcessing == False:
                time.sleep(1)
                continue

            GPIO.wait_for_edge(Din2, GPIO.RISING)
            if GPIO.input(Din2) != GPIO.HIGH:
                continue

            if obj.counterProcessing == False:
                continue

            # 发出清空标识
            obj.counterNewValue.emit(-1)
            obj.openLightDelayClose()
            #GPIO.remove_event_detect(Din2)
            count = ImageCounter.capAndAnalysis()
            SoundPlayer.play(count)
            obj.counterNewValue.emit(count)
            print("\n GPIO: Rising Edge Detected.Sending message to DingTalk.")
            #GPIO.add_event_detect(Din2, GPIO.RISING, callback=hwHandler.cb_func_counter, bouncetime=200)

    # 上升沿触发回调处理任务
    def cb_func_counter(self, sa):
        # 防止回弹
        if GPIO.input(Din2) != GPIO.HIGH:
            return
        GPIO.remove_event_detect(Din2)
        count = ImageCounter.capAndAnalysis()
        SoundPlayer.play(count)
        CounterHandler.counterNewValue.emit(count)
        print("\n GPIO: Rising Edge Detected.Sending message to DingTalk.")
        GPIO.add_event_detect(Din2, GPIO.RISING, callback=self.cb_func_counter, bouncetime=200)

    def bindPinHandler(self):
        # 显示后注册监听事件
        # GPIO.add_event_detect(Din2, GPIO.FALLING)  ##注册一个检测电压由低变高事件
        # GPIO.add_event_callback(Din2, self.cb_func_counter, bouncetime=200)  ##检测到事件触发回调getRespose 函数
        GPIO.add_event_detect(Din2, GPIO.RISING, callback=self.cb_func_counter, bouncetime=200)
        print('add din2 interrupt event')

    def unBindPinHandler(self):
        #窗口关闭时取消注册中断监听，避免误操作
        GPIO.remove_event_detect(Din2)
        print('removed din2 interrupt event')
